package com.ce.sys.cleanfile.logic.search;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.net.ftp.FTPClient;

import com.ce.framework.datamaintain.dao.IBaseDao;
import com.ce.framework.datamaintain.implement.BaseLogic;
import com.ce.framework.exception.AppException;
import com.ce.framework.exception.DaoException;
import com.ce.sys.cleanfile.dao.po.SysFileCleanInf;
import com.ce.sys.cleanfile.dto.KeyValueDto;
import com.ce.sys.login.model.User;
import com.ce.util.DbUtil;
import com.ce.util.NetFileUtil;
import com.ce.util.RegeditUtil;

public class FileCleanLogic extends BaseLogic implements IFileCleanLogic {
    
    private IBaseDao basedao;
    
    public IBaseDao getBasedao() {
        return basedao;
    }

    public void setBasedao(IBaseDao basedao) {
        this.basedao = basedao;
    }

    /**
     * @author ： andy
     * @since： Oct 26, 2011 8:15:08 AM
     * 功能描述：清除服务器中的无用附件
     * 算法：1 获取SYS_T_FILE_CLEAN_INF表中要删除的带附件的表名及附件字段
     *      2 获取带附件的表中记录标记为删除，并且在附件表中标记为未删除的附件id的附件数据，
     *      3 根据第二步获取到的附件数据删除服务器上的附件（分两种删除，1 存放与WEB服务器的附件删除，2 存放于FTP服务器的附件删除）
     *      4 更新SYS_T_FILE_CLEAN_INF表，将表中主键等于第二步获取的附件id的记录的删除标记设置为已删除（标记为1）
     *      5 返回第二步获取的附件id的数量
     * 方法的参数和返回值
     * @return
     * @throws AppException
     * int  附件的删除数量
     * ==================================
     * 修改历史
     * 修改人        修改时间      修改原因及内容
     *
     * ==================================
     */
	public int deleteCleanFiles() throws AppException {
		int sum = 0;
		String hql = "from SysFileCleanInf s where s.vcDelFlag = 0";
		List<String> falseFile = new ArrayList<String>(0);
		List<SysFileCleanInf> fileCleanList = new ArrayList<SysFileCleanInf>(0);
		try {
			List ss = this.basedao.findByHql(hql);
			for(int i = 0; i < ss.size(); i++){
				SysFileCleanInf sys = (SysFileCleanInf)ss.get(i);
				String table = sys.getVcTableName();
				String fileColumn = sys.getVcFileColumName();
				KeyValueDto<Integer,List<String>> kvd = cleanFileByProperty(table,fileColumn);
				sum+=kvd.getKey();
				falseFile.addAll(kvd.getValue());
				updateSysFileCleanInf(fileCleanList, sys);
			}
			//更新list<SysFileCleanInf>
			this.basedao.updatePos(fileCleanList);
		} catch (DaoException e) {
			throw new AppException("系统出现错误！");
		}
		return sum;
	}

	/**
	 * 开发人： andy
	 * 开发时间： 2013-10-26 下午12:47:17
	 * 功能描述：把需要更新的SysFileCleanInf对象放入List集合
	 * 方法的参数和返回值
	 * @param fileCleanList list集合
	 * @param sys SysFileCleanInf对象
	 * void 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	private void updateSysFileCleanInf(List<SysFileCleanInf> fileCleanList,
			SysFileCleanInf sys) {
		sys.setVcUser(User.getUserName());
		sys.setDtLastClean(new Date());
		fileCleanList.add(sys);
	}

	/**
	 * 开发人： andy
	 * 开发时间： 2013-10-26 上午10:03:12
	 * 功能描述：根据表名和该表中存放文件ID的列名删除服务器上的文件
	 * 方法的参数和返回值
	 * @param table 表名
	 * @param fileColumn 存放文件ID的列名
	 * @return 删除的文件总数
	 * int 文件总数
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 * @throws AppException 
	 */
	private KeyValueDto<Integer, List<String>> cleanFileByProperty(String table, String fileColumn) throws AppException {
		StringBuffer sb = new StringBuffer("select p.vc_id,p.VC_CHILD$FOLDER,p.VC_FILENAME from ");
		sb.append(table).append(" t, pub_t_file_upload_log p")
		.append(" where t."+fileColumn)
		.append(" = p.vc_id")
		.append(" and t.vc_del$flag = 1 and p.vc_del$flag = 0");
		List objlist = DbUtil.executeSqlQueryToObj(sb.toString());
		List<String> fileFalse = new ArrayList<String>(0);
		for(int i = 0; i< objlist.size(); i++){
			Object[] obj  = (Object[])objlist.get(i);
			String fileId = obj[0].toString();
			String childFolder = obj[1].toString();
			String fileName = obj[2].toString();
			String dir = RegeditUtil.getRegeditStringValue("WEB_SERVER_FILE_DIR");
			if(dir.length()==0){
				dir = "D:/csmisfiles/ftpfile/";
			}
			//如果配置了多个目录，则使用最后一个目录做为存储根路径
			else if(dir.lastIndexOf(";")>=0){
				dir = dir.substring(dir.lastIndexOf(";")+1);
			}
			String fileUrl = dir+childFolder+fileId;
			String saveType = RegeditUtil
			.getRegeditStringValue("USE_FTP_SERVER");
			if("true".equals(saveType)){
				deleteFileFromFtp(fileFalse,fileId,fileName,childFolder+fileId);
			}else{
				deleteFileFromService(fileFalse, fileId, fileName, fileUrl);
			}
		}
		return new KeyValueDto<Integer, List<String>>(objlist.size(),fileFalse);
	}

	/**
	 * 开发人： andy
	 * 开发时间： 2013-10-27 下午01:33:27
	 * 功能描述：删除FTP服务器上面的文件
	 * 方法的参数和返回值
	 * @param fileFalse 每个删除失败的附件都会有提醒，组成一个集合
	 * @param fileId 文件Id
	 * @param fileName 文件名称
	 * @param filePath 文件路径
	 * void 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	private void deleteFileFromFtp(List<String> fileFalse, String fileId,
			String fileName, String filePath) throws AppException{
		 FTPClient ftpClient = NetFileUtil.getFTPUpClient();
		 try{
			 String[] dirArray = filePath.split("/");
			   if (dirArray.length > 1) {
			    for (int i = 0; i < dirArray.length - 1; i++) {
			     if (dirArray[i] != null) {
			    	 ftpClient.changeWorkingDirectory(dirArray[i]);
			     }
			    }
			   }
			   boolean flag = ftpClient.deleteFile(dirArray[dirArray.length - 1]);
			   updateFileUploadLog(fileFalse, fileId, fileName, flag);
		 }catch(Exception e){
			   updateFileUploadLog(fileFalse, fileId, fileName, false);
		 }
		


		
	}

	private void updateFileUploadLog(List<String> fileFalse, String fileId,
			String fileName, boolean flag) {
		if(flag == false){
				String warn = "文件ID为："+fileId+"文件名为："+fileName+"的文件删除失败";
				fileFalse.add(warn);
			}else{
				String sql = "UPDATE pub_t_file_upload_log SET VC_DEL$FLAG = 1 WHERE VC_ID = '"+fileId+"'";
				DbUtil.executeSqlUpdate(sql);
			}
	}

	/**
	 * 开发人： andy
	 * 开发时间： 2013-10-27 上午09:01:18
	 * 功能描述：删除普通服务器上面的文件
	 * 方法的参数和返回值
	 * @param fileFalse 每个删除失败的附件都会有提醒，组成一个集合
	 * @param fileId 文件ID
	 * @param fileName 文件名称
	 * @param fileUrl 存放文件的Url
	 * void 
	 * ==================================
	 * 修改历史
	 * 修改人        修改时间      修改原因及内容
	 *
	 * ==================================
	 */
	private void deleteFileFromService(List<String> fileFalse, String fileId,
			String fileName, String fileUrl) {
		File file = new File(fileUrl);
		boolean flag = false;
		if(file.exists()){
			flag = file.delete();
			updateFileUploadLog(fileFalse, fileId, fileName, flag);
		}
	}

}
